<?php

namespace backend\models;

use Yii;
use yii\web\UploadedFile;
use Da\User\Model\User;
use backend\helpers\FileNameInflector;
/**
 * This is the model class for table "contract".
 *
 * @property int $id
 * @property int|null $own_number
 * @property int|null $contractor_number
 * @property int $id_contractor
 * @property string|null $subject
 * @property float|null $total_price
 * @property string|null $date_sign
 * @property string|null $date_realize
 * @property string|null $comment
 *
 * @property Contractor $contractor
 */
class Contract extends \yii\db\ActiveRecord
{
    const CONTRACTS_PATH = '@backend/web/edo-archive/contracts/';
    const BUCKET_NAME = 'ogikm-contracts';

    const ONE_TIME = 0;
    const YEAR_TIME = 1;

    public $dateSignStart;
    public $dateSignEnd;

    public $dateRealizeStart;
    public $dateRealizeEnd;

    public $docKpRequestOne;
    public $docKpRequestTwo; 
    public $docKpAnswerOne; 
    public $docKpAnswerTwo;
    public $docKpScreenshot;
    public $docMainContract;
    public $docInvoice;
    public $docClose;
    public $docPaymentOrder;

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'contract';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            ['registry_number', 'unique'],
            [['id_contractor', 'id_finance_source', 'id_status', 'id_donor', 'id_project', 'id_liable_user', 'id_purchase_method', 'id_purpose', 'id_organization_branch', 'registry_number', 'is_yearly'], 'integer'],
            [['id_contractor', 'id_finance_source', 'id_status', 'own_number'], 'required'],
            [['total_price'], 'number'],
            [['date_sign', 'date_realize', 'dateSignStart', 'dateSignEnd', 'dateRealizeStart', 'dateRealizeEnd'], 'safe'],
            [['comment'], 'string'],
            [['own_number', 'contractor_number'], 'string', 'max' => 255],
            [['subject', 'doc_kp_request_one', 'doc_kp_request_two', 'doc_kp_answer_one', 'doc_kp_answer_two', 'doc_main_contract', 'doc_kp_screenshot', 'doc_invoice', 'doc_close', 'doc_payment_order'], 'string', 'max' => 512],
            [['id_contractor'], 'exist', 'skipOnError' => true, 'targetClass' => Contractor::className(), 'targetAttribute' => ['id_contractor' => 'id']],
            [['id_finance_source'], 'exist', 'skipOnError' => true, 'targetClass' => FinanceSource::className(), 'targetAttribute' => ['id_finance_source' => 'id']],
            [['docKpRequestOne', 'docKpRequestTwo', 'docKpAnswerOne', 'docKpAnswerTwo', 'docInvoice', 'docClose', 'docPaymentOrder'], 'file', 'extensions' => 'doc, docx, pdf, zip', 'maxSize' => 1024*1024*12],
            [['docKpScreenshot', 'docMainContract'], 'file', 'extensions' => 'doc, docx, pdf, zip', 'maxSize' => 1024*1024*30],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'registry_number' => 'Реестровый номер',
            'own_number' => 'Номер договора',
            'contractor_number' => 'Номер договора (контрагента)',
            'id_contractor' => 'Контрагент',
            'id_status' => 'Статус',
            'id_finance_source' => 'Источник финансирования',
            'id_donor' => 'Донор',
            'id_project' => 'Проект',
            'id_liable_user' => 'Ответственный сотрудник',
            'id_purchase_method' => 'Способ закупки',
            'id_purpose' => 'Цель закупки',
            'id_organization_branch' => 'Филиал',
            'subject' => 'Предмет договора',
            'total_price' => 'Сумма',
            'date_sign' => 'Дата заключения',
            'dateSignStart' => 'Дата заключения (c)',
            'dateSignEnd' => 'Дата заключения (по)',
            'date_realize' => 'Дата завершения обязательств',
            'dateRealizeStart' => 'Дата завершения обязательств (с)',
            'dateRealizeEnd' => 'Дата завершения обязательств (по)',
            'comment' => 'Комментарий',
            'doc_kp_request_one' => 'Запрос коммерческого предложения №1',
            'doc_kp_request_two' => 'Запрос коммерческого предложения №2',
            'doc_kp_answer_one' => 'Коммерческое предложение №1',
            'doc_kp_answer_two' => 'Коммерческое предложение №2',
            'doc_kp_screenshot' => 'Специальная версия КП (скриншоты)',
            'doc_main_contract' => 'Договор',
            'doc_invoice' => 'Счёт',
            'doc_close' => 'Закрывающий документ',
            'doc_payment_order' => 'Платёжное поручение',
            'docKpRequestOne' => 'Запрос коммерческого предложения №1', 
            'docKpRequestTwo' => 'Запрос коммерческого предложения №2', 
            'docKpAnswerOne' => 'Коммерческое предложение №1', 
            'docKpAnswerTwo' => 'Коммерческое предложение №2', 
            'docKpScreenshot' => 'Специальная версия КП (скриншоты)',
            'docMainContract' => 'Договор',
            'docInvoice' => 'Счёт',
            'docClose' => 'Закрывающий документ',
            'docPaymentOrder' => 'Платёжное поручение',
            'is_yearly' => 'Заключен на год',
        ];
    }

    public static function generateRegistryNumber()
    {
        return random_int(10000000, 99999999);
    }

    /**
     * Gets query for [[Contractor]].
     *
     * @return \yii\db\ActiveQuery
     */
    public function getContractor()
    {
        return $this->hasOne(Contractor::className(), ['id' => 'id_contractor']);
    }

    public function getFinanceSource()
    {
        return $this->hasOne(FinanceSource::className(), ['id' => 'id_finance_source']);
    }

    public function getDonor()
    {
        return $this->hasOne(Donor::className(), ['id' => 'id_donor']);
    }

    public function getProject()
    {
        return $this->hasOne(Project::className(), ['id' => 'id_project']);
    }

    public function getStatus()
    {
        return $this->hasOne(ContractStatus::className(), ['id' => 'id_status']);
    }

    public function getPurchaseMethod()
    {
        return $this->hasOne(ContractPurchaseMethod::className(), ['id' => 'id_purchase_method']);
    }

    public function getPurpose()
    {
        return $this->hasOne(ContractPurpose::className(), ['id' => 'id_purpose']);
    }

    public function getOrganizationBranch()
    {
        return $this->hasOne(OrganizationBranch::className(), ['id' => 'id_organization_branch']);
    }

    public function getLiableUser()
    {
        return $this->hasOne(User::className(), ['id' => 'id_liable_user']);
    }

    public function getAgreements()
    {
        return $this->hasMany(Agreement::class, ['contract_id' => 'id']);
    }

    public function getFiles()
    {
        return $this->hasMany(ContractFile::class, ['id_contract' => 'id']);
    }

    public function beforeSave($insert)
    {
        if (!parent::beforeSave($insert)) {
            return false;
        }

        // Запись новая
        if($insert)
        {
            // Спокойно сохраняем все файлы
            $this->insertContracts();
        }
        // Запись обновляется
        else
        {
            // Необходимы дополнительные проверки
            $this->updateContracts();
        }
        
        return true;
    }

    public function beforeDelete()
    {
        if (!parent::beforeDelete()) {
            return false;
        }

        $this->deleteContracts();

        return true;
    }
  
    private function insertContracts()
    {
        if($this->docKpRequestOne) $this->doc_kp_request_one = $this->uploadFile($this->docKpRequestOne, $this->generateKPRequestOneName());
        if($this->docKpRequestTwo) $this->doc_kp_request_two = $this->uploadFile($this->docKpRequestTwo, $this->generateKPRequestTwoName());
        if($this->docKpAnswerOne) $this->doc_kp_answer_one = $this->uploadFile($this->docKpAnswerOne, $this->generateKPAnswerOneName());
        if($this->docKpAnswerTwo) $this->doc_kp_answer_two = $this->uploadFile($this->docKpAnswerTwo, $this->generateKPAnswerTwoName());
        if($this->docKpScreenshot) $this->doc_kp_screenshot = $this->uploadFile($this->docKpScreenshot, $this->generateKPScreenshotName());
        if($this->docMainContract) $this->doc_main_contract = $this->uploadFile($this->docMainContract, $this->generateMainContractName());
        if($this->docInvoice) $this->doc_invoice = $this->uploadFile($this->docInvoice, $this->generateInvoiceName());
        if($this->docClose) $this->doc_close = $this->uploadFile($this->docClose, $this->generateCloseName());
        if($this->docPaymentOrder) $this->doc_payment_order = $this->uploadFile($this->docPaymentOrder, $this->generatePaymentOrderName());
    }

    private function updateContracts()
    {
        //если есть запись в БД и поле измененено - удалять
        if($this->docKpRequestOne) 
        { 
            if($this->doc_kp_request_one)
            {
                $this->deleteFile($this->doc_kp_request_one);
            }
            $this->doc_kp_request_one = $this->uploadFile($this->docKpRequestOne, $this->generateKPRequestOneName());
        }
        if($this->docKpRequestTwo) 
        { 
            if($this->doc_kp_request_two)
            {
                $this->deleteFile($this->doc_kp_request_two);
            }
            $this->doc_kp_request_two = $this->uploadFile($this->docKpRequestTwo, $this->generateKPRequestTwoName());
        }
        if($this->docKpAnswerOne) 
        { 
            if($this->doc_kp_answer_one)
            {
                $this->deleteFile($this->doc_kp_answer_one);
            }
            $this->doc_kp_answer_one = $this->uploadFile($this->docKpAnswerOne, $this->generateKPAnswerOneName());
        }
        if($this->docKpAnswerTwo) 
        { 
            if($this->doc_kp_answer_two)
            {
                $this->deleteFile($this->doc_kp_answer_two); 
            }
            $this->doc_kp_answer_two = $this->uploadFile($this->docKpAnswerTwo, $this->generateKPAnswerTwoName());
        }
        if($this->docKpScreenshot) 
        { 
            if($this->doc_kp_screenshot)
            {
                $this->deleteFile($this->doc_kp_screenshot); 
            }
            $this->doc_kp_screenshot = $this->uploadFile($this->docKpScreenshot, $this->generateKPScreenshotName());
        }
        if($this->docMainContract) 
        { 
            if($this->doc_main_contract)
            {
                $this->deleteFile($this->doc_main_contract); 
            }
            $this->doc_main_contract = $this->uploadFile($this->docMainContract, $this->generateMainContractName());
        }
        if($this->docInvoice) 
        { 
            if($this->doc_invoice)
            {
                $this->deleteFile($this->doc_invoice); 
            }
            $this->doc_invoice = $this->uploadFile($this->docInvoice, $this->generateInvoiceName());
        }
        if($this->docClose) 
        { 
            if($this->doc_close)
            {
                $this->deleteFile($this->doc_close); 
            }
            $this->doc_close = $this->uploadFile($this->docClose, $this->generateCloseName());
        }
        if($this->docPaymentOrder) 
        { 
            if($this->doc_payment_order)
            {
                $this->deleteFile($this->doc_payment_order); 
            }
            $this->doc_payment_order = $this->uploadFile($this->docPaymentOrder, $this->generatePaymentOrderName());
        }
    }

    private function deleteContracts()
    {
        $this->deleteFile($this->doc_kp_request_one);
        $this->deleteFile($this->doc_kp_request_two);
        $this->deleteFile($this->doc_kp_answer_one);
        $this->deleteFile($this->doc_kp_answer_two); 
        $this->deleteFile($this->doc_kp_screenshot); 
        $this->deleteFile($this->doc_main_contract);
        $this->deleteFile($this->doc_invoice); 
        $this->deleteFile($this->doc_close); 
        $this->deleteFile($this->doc_payment_order);  
    }

    private function uploadFile($file, $fileName = null)
    {
        if($fileName != null)
        {
            $fileName = $fileName . '.' . $file->extension;
        }
        else
        {
            $fileName = $file->name;
        }

        if($file)
        {
            $s3 = Yii::$app->get('s3');
            $result = $s3->commands()->upload($fileName, $file->tempName)->inBucket(self::BUCKET_NAME)->withAcl('private')->execute();
            return $fileName;
        }
        else 
        {
            return null;
        }
    }

    private function deleteFile($fileName)
    {
        if($fileName)
        {
            $s3 = Yii::$app->get('s3');
            $s3->commands()->delete($fileName)->inBucket(self::BUCKET_NAME)->execute();
        }
    }

    private function generateKPRequestOneName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Запрос КП №1';
    }

    private function generateKPRequestTwoName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Запрос КП №2';
    }

    private function generateKPAnswerOneName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - КП №1';
    }

    private function generateKPAnswerTwoName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - КП №2';
    }

    private function generateKPScreenshotName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Скриншоты цен';
    }

    private function generateMainContractName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')';
    }

    private function generateInvoiceName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Счёт';
    }

    private function generateCloseName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Закрывающий документ';
    }

    private function generatePaymentOrderName()
    {
        return 'Договор №' . FileNameInflector::specialSlug($this->own_number) . ' (' . $this->registry_number . ')' . ' - Платёжное поручение';
    }    
}
